I'm trying to match [abc] unless it's "escaped" by [] from both sides (so [[abc]] is considered as escaped, but not [[abc] or [abc]]).
Closest thing I could find is (?<!\[)\[abc\](?!\]) from Match "ABC" from *ABC*, but not from **ABC**, but it ignores match if it's escaped from only one side.
The lookahead could be either at the left, or at the right to allow a single backet on the left or right, but not a double square bracket on the other side.
(?<!\[)\[abc]|\[abc](?!])
@Thefourthbird's answer works, but would require that the main pattern abc be repeated, which goes against the DRY principle that most are encouraged to follow.
In the interest of maximizing code reuse, one approach would be to use a capture group to capture [abc] and then use it in a negative lookbehind pattern to ensure that it is not both preceded by a [ and followed by a ]:
(\[abc])(?<!\[\1(?=]))
Note that this works for C# because .NET happens to support variable-length lookbehind patterns, which aren't supported by many other regex engines.